#include "sem.hpp"
#include <vector>
using namespace SemModule;
const int MAXQUEUECAP = 5;
namespace RunningQueueModule
{
    template <typename T>
    class RuningQueue
    {
    private:
        void Lock(pthread_mutex_t &mutex)
        {
            pthread_mutex_lock(&mutex);
        }
        void Unlock(pthread_mutex_t &mutex)
        {
            pthread_mutex_unlock(&mutex);
        }

    public:
        RuningQueue()
            : _capacity(MAXQUEUECAP),
              _pindex(0),
              _cindex(0),
              _q(MAXQUEUECAP),
              _room_sem(MAXQUEUECAP),
              _data_sem(0)
        {
            pthread_mutex_init(&_cmutex, nullptr);
            pthread_mutex_init(&_pmutex, nullptr);
        }
        ~RuningQueue()
        {
            pthread_mutex_destroy(&_pmutex);
            pthread_mutex_destroy(&_cmutex);
        }
        void Enqueue(const T &in)
        {
            // 生产者
            //先预定资源
            _room_sem.P();
            Lock(_pmutex);
            _q[_pindex]=in;
            _pindex++;
            _pindex%=_capacity;
            _data_sem.V();
            
            Unlock(_pmutex);
        }
        void Pop(T *out)
        {
            // 消费者
            _data_sem.P();
            Lock(_cmutex);
            *out=_q[_cindex];
            _cindex++;
            _cindex%=_capacity;
            _room_sem.V();
            Unlock(_cmutex);
           
        }

    private:
        std::vector<T> _q; // 模拟环形队列
        int _capacity;
        int _pindex;             // 生产者下标
        int _cindex;             // 消费者下标
        pthread_mutex_t _pmutex; // 维护生产者之间的互斥关系的锁
        pthread_mutex_t _cmutex; // 消费者

        Sem _room_sem; // ⽣产者关⼼
        Sem _data_sem; // 消费者关⼼
    };
}
